#include "stdafx.h"
#include "libraries.h"

#include "Application.h"
#include "Filesystem.h"

#include "RenderTarget.h"

using namespace Cvekas;

class RenderToTexture: public Application
{
public:
	RenderToTexture(HINSTANCE instance, const std::string& name, const std::string& log_filename)
		: Application(instance, name, log_filename)
	{
		Filesystem::init();
	}

	virtual ~RenderToTexture()
	{
	}

	virtual void initVideoDevice()
	{
		settings->insert("video", VideoSettings());

		(*settings)["video"]["ScreenWidth"] = 800;
		(*settings)["video"]["ScreenHeight"] = 600;
		(*settings)["video"]["VSync"] = false;
		(*settings)["video"]["Fullscreen"] = false;

		window = WindowPtr(new Window(instance, name));
		video_device->init(window);
	}

	virtual void init()
	{
		balls = texture_manager->loadTexture2D("balls", Filesystem::redirect("balls.png"));
		
		for(int i = 0; i < 7; ++i)
			src_balls[i] = RectF(64.0f * float(i), 0.0f, 64.0f, 64.0f);

		render_target = texture_manager->createRenderTarget("rt1", 256, 256, D3DFMT_X8R8G8B8);

		sprite_batch = video_device->createSpriteBatch(main_renderer, 800, 600, 0);
	}

	virtual bool update()
	{
		return true;
	}

	virtual bool render()
	{
		// Render scene to render target once...
		video_device->setClearColor(Color(255, 255, 255));
		video_device->beginScene(true, true, false, render_target);

		sprite_batch->setVirtualResolution(256, 256);
		
		for(int i = 0; i < 7; ++i)
		{
			float t = float(Timer::getTimeMs()) / 1000.0f;
			float x = sin(t * (1.0f + sin(t / 4.0f) / 4.0f) + (float(i) / 7.0f) * 2.0f * pi);
			float y = cos(t * 1.6f + (float(i) / 7.0f) * 2.0f * pi);
			sprite_batch->draw(balls, 0, src_balls[i], Vector2(96.0f + x * (128.0f-32.0f), 96.0f + y * (128.0f-32.0f)));
		}

		sprite_batch->present();
		main_renderer->render();

		video_device->endScene();

		// Then draw multiple copies of scene using render target as a texture
		video_device->setClearColor(Color(0, 0, 0));
		video_device->beginScene();
		
		sprite_batch->setVirtualResolution(800, 600);
		
		sprite_batch->draw(render_target, 1, Vector2(5.0f, 5.0f));
		sprite_batch->draw(render_target, 1, Vector2(5.0f, 600.0f - 256.0f - 5.0f));
		sprite_batch->draw(render_target, 1, Vector2(800.0f - 256.0f - 5.0f, 5.0f));
		sprite_batch->draw(render_target, 1, Vector2(800.0f - 256.0f - 5.0f, 600.0f - 256.0f - 5.0f));
		
		sprite_batch->present();
		// To avoid rendering balls twice, only render batches with priority 1 
		main_renderer->render(1, 1);
		
		video_device->endScene();
		main_renderer->endFrame();

		return true;
	}

private:
	Texture2DPtr balls;
	RenderTargetPtr render_target;

	RectF src_balls[7];

	SpriteBatchPtr sprite_batch;
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
	try
	{
		RenderToTexture app(hInstance, "RenderToTexture", "RenderToTexture.log");
		app.run();
	}
	catch (std::exception& e)
	{
		MessageBox(NULL, e.what(), "Fatal error", NULL);
	}
	return 0;
}
